# -*- encoding:utf-8 -*-
# __author__ = 'chenyongbing'
# __poject__ = 'ops_platform'
# __datetime__ = '2022/2/28'
# __name__ = 'serializers.py'

# Create your code here.
from rest_framework.validators import UniqueTogetherValidator
from rest_framework import serializers
from .models import *
from .enums import OrderChoices
from apps.cicd.cache import *
from apps.resource.serializers import BusinessSerializer, ProjectSerializer, ServiceSerializer

class BusinessEnvSettingSerializer(BusinessSerializer):
    env_count = serializers.SerializerMethodField()

    def get_env_count(self, obj):
        les = LobEnvSetting.objects.filter(business_id=obj.id, project_id=None, service_id=None).count()
        return les

    class Meta:
        model = BusinessSerializer.Meta.model
        fields = ['id', 'name', 'code', 'env_count']

class ProjectEnvSettingSerializer(ProjectSerializer):
    env_count = serializers.SerializerMethodField()

    def get_env_count(self, obj):
        les = LobEnvSetting.objects.filter(project_id=obj.id, service_id=None).count()
        return les

    class Meta:
        model = ProjectSerializer.Meta.model
        fields = ['id', 'name', 'code', 'env_count', 'business']

class ServiceEnvSettingSerializer(ServiceSerializer):
    env_count = serializers.SerializerMethodField()

    def get_env_count(self, obj):
        les = LobEnvSetting.objects.filter(service_id=obj.id).count()
        return les

    class Meta:
        model = ServiceSerializer.Meta.model
        fields = ['id', 'name', 'code', 'env_count', 'business', 'project']


class CapacitySerializer(serializers.ModelSerializer):
    resources = serializers.SerializerMethodField(source='get_resources', read_only=True)
    class Meta:
        model = Capacity
        fields = '__all__'

    def get_resources(self, obj):
        java_memory = str(int(obj.memory * int(1000 * 0.8)))
        return {'resources': {
                    'limits': {'cpu': str(obj.cpu), 'memory': str(int(obj.memory * 1000)) + 'Mi'},
                    'requests': {'cpu': str(obj.cpu) if obj.cpu <= 0.1 else '0.1', 'memory': str(int(obj.memory * 1000)) + 'Mi'}
                },
                'env': [
                    {'name': 'JAVA_OPTS', 'value': "-Xms{memory}m -Xmx{memory}m".format(memory=java_memory)}
                ]
        }
        
class YAMLTemplateSerializer(serializers.ModelSerializer):
    class Meta:
        model = YAMLTemplate
        fields = '__all__'
        
# class BusinessEnvSettingSerializer(serializers.ModelSerializer):
#     env_name = serializers.SerializerMethodField(source='get_env_name', read_only=True)
#     kube_name = serializers.SerializerMethodField(source='get_kube_name', read_only=True)
#     capacity_name = serializers.SerializerMethodField(source='get_capacity_name', read_only=True)
#     # template_name = serializers.SerializerMethodField(source='get_template_name')
#     class Meta:
#         model = BusinessEnvSetting
#         fields = '__all__'
#     def get_env_name(self, obj):
#         # return get_env_name(obj.env_id)
#         return obj.env.name
# 
#     def get_kube_name(self, obj):
#         # return get_kube_name(obj.kube_id)
#         return obj.kube.name
# 
#     def get_capacity_name(self, obj):
#         return obj.capacity.name
# 
#     def get_template_name(self, obj):
#         return obj.template.name
# 
# class ProjectEnvSettingSerializer(serializers.ModelSerializer):
#     env_name = serializers.SerializerMethodField(source='get_env_name', read_only=True)
#     kube_name = serializers.SerializerMethodField(source='get_kube_name', read_only=True)
#     capacity_name = serializers.SerializerMethodField(source='get_capacity_name', read_only=True)
#     template_name = serializers.SerializerMethodField(source='get_template_name', read_only=True)
#     class Meta:
#         model = ProjectEnvSetting
#         fields = '__all__'
#     def get_env_name(self, obj):
#         # return get_env_name(obj.env_id)
#         return obj.env.name
#     def get_kube_name(self, obj):
#         # return get_kube_name(obj.kube_id)
#         return obj.kube.name
# 
#     def get_capacity_name(self, obj):
#         return obj.capacity.name
#     def get_template_name(self, obj):
#         return obj.template.name
#         
# class ServiceEnvSettingSerializer(serializers.ModelSerializer):
#     env_name = serializers.SerializerMethodField(source='get_env_name', read_only=True)
#     kube_name = serializers.SerializerMethodField(source='get_kube_name', read_only=True)
#     capacity_name = serializers.SerializerMethodField(source='get_capacity_name', read_only=True)
#     template_name = serializers.SerializerMethodField(source='get_template_name', read_only=True)
#     class Meta:
#         model = ServiceEnvSetting
#         fields = '__all__'
#         
#     def get_env_name(self, obj):
#         # return get_env_name(obj.env_id)
#         return obj.env.name
#     def get_kube_name(self, obj):
#         # return get_kube_name(obj.kube_id)
#         return obj.kube.name
# 
#     def get_capacity_name(self, obj):
#         return obj.capacity.name
#     def get_template_name(self, obj):
#         return obj.template.name


class LobEnvSettingSerializer(serializers.ModelSerializer):
    env_name = serializers.SerializerMethodField(source='get_env_name', read_only=True)
    kube_name = serializers.SerializerMethodField(source='get_kube_name', read_only=True)
    capacity_name = serializers.SerializerMethodField(source='get_capacity_name', read_only=True)
    template_name = serializers.SerializerMethodField(source='get_template_name', read_only=True)
    repo_name = serializers.SerializerMethodField(source='get_repo_name', read_only=True)

    class Meta:
        model = LobEnvSetting
        fields = '__all__'


    def validate(self, attrs):
        business_id = attrs.get('business_id', None)
        project_id = attrs.get('project_id', None)
        service_id = attrs.get('service_id', None)
        env_id = attrs.get('env_id', None)

        try:
            obj = self.Meta.model.objects.get(business_id=business_id, project_id=project_id, service_id=service_id, env_id=env_id)
        except self.Meta.model.DoesNotExist:
            return attrs
        if self.instance and obj.id == self.instance.id:
            return attrs
        else:
            raise serializers.ValidationError('already exists')

    def get_env_name(self, obj):
        # return get_env_name(obj.env_id)
        return get_env_name_cache(obj.env_id)

    def get_kube_name(self, obj):
        return get_kube_name_cache(obj.kube_id)
        # return obj.kube.name
    def get_capacity_name(self, obj):
        return get_capacity_name_cache(obj.capacity_id)

    def get_template_name(self, obj):
        return get_template_name_cache(obj.template_id)
    def get_repo_name(self, obj):
        return get_repo_name_cache(obj.repo_id)

class LobYamlSettingSerializer(serializers.ModelSerializer):
    class Meta:
        model = LobYamlSetting
        fields = '__all__'


class WorkOrderSerializer(serializers.ModelSerializer):
    service_name = serializers.SerializerMethodField(source='get_service_name', read_only=True)
    business_name = serializers.SerializerMethodField(source='get_business_name', read_only=True)
    cur_step_name = serializers.SerializerMethodField(source='get_cur_step_name', read_only=True)
    cur_deployment_info = serializers.SerializerMethodField(source='get_cur_deployment_info', read_only=True)
    capacity_name = serializers.SerializerMethodField(source='get_capacity_name', read_only=True)
    order_type_name = serializers.SerializerMethodField(source='get_order_type_name', read_only=True)
    class Meta:
        model = WorkOrder
        fields = '__all__'

    def get_service_name(self, obj):
        # return obj.service.name
        return get_service_name_cache(obj.service_id)
    def get_business_name(self, obj):
        # return obj.service.business.name
        return get_business_name_cache_by_service(obj.service_id)
    def get_cur_step_name(self, obj):
        if obj.steps.last():
            return obj.steps.last().step.name

    def get_capacity_name(self, obj):
        return get_capacity_name_cache(obj.capacity_id)

    def get_cur_deployment_info(self, obj):
        info = get_deployment_info_cache(obj.service.code, obj.env.code)
        if not info: return {}
        available_replicas = info.get('status', {}).get('available_replicas', 0) or 0
        replicas = info.get('replicas', 0) or 0
        return {'imagetag': info.get('imagetag'), 'status': '{}/{}'.format(available_replicas, replicas)}

    def get_order_type_name(self, obj):
        return dict(OrderChoices).get(obj.order_type)

class WorkOrderRunSerializer(serializers.Serializer):
    step = serializers.CharField()
    action = serializers.CharField()
    


class FlowSerializer(serializers.ModelSerializer):
    class Meta:
        model = Flow
        fields = '__all__'

# class StageSerializer(serializers.ModelSerializer):
#     class Meta:
#         model = Stage
#         fields = '__all__'

class StepSerializer(serializers.ModelSerializer):
    class Meta:
        model = Step
        fields = '__all__'

# 
# class FlowStageSerializer(serializers.ModelSerializer):
#     class Meta:
#         model = FlowStage
#         fields = '__all__'
# 
# 
# class StageStepSerializer(serializers.ModelSerializer):
#     class Meta:
#         model = StageStep
#         fields = '__all__'


class WorkOrderStepSerializer(serializers.ModelSerializer):
    class Meta:
        model = WorkOrderStep
        fields = '__all__'


class DemandOrderSerializer(serializers.ModelSerializer):
    business_name = serializers.SerializerMethodField(source="get_business_name", read_only=True)
    env_name = serializers.SerializerMethodField(source="get_env_name", read_only=True)
    service_count = serializers.SerializerMethodField(source="get_service_count", read_only=True)

    def get_business_name(self, obj):
        # return obj.business.name
        return get_business_name_cache(obj.business_id)
    def get_env_name(self, obj):
        # return obj.env.name
        return get_env_name_cache(obj.env_id)

    def get_service_count(self, obj):
        return len(obj.orders.filter(delete=0))

    class Meta:
        model = DemandOrder
        fields = '__all__'





class DemandMultiChildOrderSerializer(serializers.ModelSerializer):
    demand = serializers.IntegerField()
    orders = WorkOrderSerializer(many=True)

